package vip.xiaonuo.bi.modular.dataset.enums;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;

/**
 *
 *   @auther: 顾育司
 *  @Description 日常时间函数 这里主要用与doris的动态时间
 *  @date: 2024/1/6
 *
 */
public  enum DateFunc {
    /**
     * 今天  TODAY
     * 昨天	YESTERDAY
     * 明天	TOMORROW
     * 本周	THIS_WEEK
     * 上周	LAST_WEEK
     * 下周	NEXT_WEEK
     * 本月	THIS_MONTH
     * 上个月	LAST_MONTH
     * 下个月	NEXT_MONTH
     * 本季度	THIS_QUARTER
     * 上季度	LAST_QUARTER
     * 下季度	NEXT_QUARTER
     * 今年	THIS_YEAR
     * 去年	LAST_YEAR
     * 明年	NEXT_YEAR
     * 过去7天	PAST_7_DAYS
     * 过去14天	PAST_14_DAYS
     * 过去30天	PAST_30_DAYS
     */
    TODAY() {
        @Override
        public String startTime() {
            return formatDate(LocalDate.now());
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.now().atTime(23, 59, 59));
        }
    },
    YESTERDAY() {
        @Override
        public String startTime() {
            return formatDate(LocalDate.now().minusDays(1));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.now().minusDays(1).atTime(23, 59, 59));
        }
    },
    TOMORROW() {
        @Override
        public String startTime() {
            return formatDate(LocalDate.now().plusDays(1));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.now().plusDays(1).atTime(23, 59, 59));
        }
    },
    THIS_WEEK() {
        @Override
        public String startTime() {
            return formatDate(LocalDate.now().with(java.time.temporal.TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY)));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.now().with(java.time.temporal.TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY)).atTime(23, 59, 59));
        }
    },
    LAST_WEEK() {
        @Override
        public String startTime() {
            LocalDate startOfWeek = LocalDate.now().minusWeeks(1).with(java.time.temporal.TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
            return formatDate(startOfWeek);
        }

        @Override
        public String entTime() {
            LocalDate endOfWeek = LocalDate.now().minusWeeks(1).with(java.time.temporal.TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY));
            return formatDate(endOfWeek.atTime(23, 59, 59));
        }
    },
    NEXT_WEEK() {
        @Override
        public String startTime() {
            LocalDate startOfWeek = LocalDate.now().plusWeeks(1).with(java.time.temporal.TemporalAdjusters.previousOrSame(java.time.DayOfWeek.MONDAY));
            return formatDate(startOfWeek);
        }

        @Override
        public String entTime() {
            LocalDate endOfWeek = LocalDate.now().plusWeeks(1).with(java.time.temporal.TemporalAdjusters.nextOrSame(java.time.DayOfWeek.SUNDAY));
            return formatDate(endOfWeek.atTime(23, 59, 59));
        }
    },
    THIS_MONTH() {
        YearMonth currentMonth = YearMonth.now();

        @Override
        public String startTime() {
            return formatDate(currentMonth.atDay(1));
        }

        @Override
        public String entTime() {
            return formatDate(currentMonth.atEndOfMonth().atTime(23, 59, 59));
        }
    },
    LAST_MONTH() {
        YearMonth previousMonth = YearMonth.now().minusMonths(1);

        @Override
        public String startTime() {
            return formatDate(previousMonth.atDay(1));
        }

        @Override
        public String entTime() {
            return formatDate(previousMonth.atEndOfMonth().atTime(23, 59, 59));
        }
    },
    NEXT_MONTH() {
        YearMonth nextMonth = YearMonth.now().plusMonths(1);

        @Override
        public String startTime() {
            return formatDate(nextMonth.atDay(1));
        }

        @Override
        public String entTime() {
            return formatDate(nextMonth.atEndOfMonth().atTime(23, 59, 59));
        }
    },
    THIS_QUARTER() {
        YearMonth currentMonth = YearMonth.now();
        int currentQuarter = (currentMonth.getMonthValue() - 1) / 3 + 1;
        int startMonthValue = (currentQuarter - 1) * 3 + 1;
        int endMonthValue = currentQuarter * 3;
        YearMonth startQuarter = YearMonth.of(currentMonth.getYear(), startMonthValue);
        YearMonth endQuarter = YearMonth.of(currentMonth.getYear(), endMonthValue);

        @Override
        public String startTime() {
            return formatDate(startQuarter.atDay(1));
        }

        @Override
        public String entTime() {
            return formatDate(endQuarter.atEndOfMonth().atTime(23, 59, 59));
        }
    },
    LAST_QUARTER() {
        YearMonth currentMonth = YearMonth.now();
        int currentQuarter = (currentMonth.getMonthValue() - 1) / 3 + 1;
        int previousQuarter = currentQuarter - 1;

        @Override
        public String startTime() {
            if (previousQuarter == 0) {
                previousQuarter = 4;
            }
            int startPreviousQuarterMonthValue = (previousQuarter - 1) * 3 + 1;
            YearMonth startPreviousQuarter = YearMonth.of(currentMonth.getYear(), startPreviousQuarterMonthValue);
            return formatDate(startPreviousQuarter.atDay(1));
        }

        @Override
        public String entTime() {
            if (previousQuarter == 0) {
                previousQuarter = 4;
            }
            int endPreviousQuarterMonthValue = previousQuarter * 3;
            YearMonth endPreviousQuarter = YearMonth.of(currentMonth.getYear(), endPreviousQuarterMonthValue);
            return formatDate(endPreviousQuarter.atEndOfMonth().atTime(23, 59, 59));
        }
    },
    NEXT_QUARTER() {
        YearMonth currentMonth = YearMonth.now();
        int currentQuarter = (currentMonth.getMonthValue() - 1) / 3 + 1;
        int nextQuarter = currentQuarter + 1;

        @Override
        public String startTime() {
            if (nextQuarter == 5) {
                nextQuarter = 1;
            }
            int startNextQuarterMonthValue = (nextQuarter - 1) * 3 + 1;
            YearMonth startNextQuarter = YearMonth.of(currentMonth.getYear(), startNextQuarterMonthValue);
            return formatDate(startNextQuarter.atDay(1));
        }

        @Override
        public String entTime() {
            if (nextQuarter == 5) {
                nextQuarter = 1;
            }
            int endNextQuarterMonthValue = nextQuarter * 3;
            YearMonth endNextQuarter = YearMonth.of(currentMonth.getYear(), endNextQuarterMonthValue);
            return formatDate(endNextQuarter.atEndOfMonth().atTime(23, 59, 59));
        }
    },
    THIS_YEAR() {
        YearMonth currentYear = YearMonth.now();

        @Override
        public String startTime() {
            return formatDate(LocalDate.of(currentYear.getYear(), Month.JANUARY, 1));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.of(currentYear.getYear(), Month.DECEMBER, 31).atTime(23, 59, 59));
        }
    },

    LAST_YEAR() {
        YearMonth previousYear = YearMonth.now().minusYears(1);

        @Override
        public String startTime() {
            return formatDate(LocalDate.of(previousYear.getYear(), Month.JANUARY, 1));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.of(previousYear.getYear(), Month.DECEMBER, 31).atTime(23, 59, 59));
        }
    },
    NEXT_YEAR() {
        YearMonth nextYear = YearMonth.now().plusYears(1);

        @Override
        public String startTime() {
            return formatDate(LocalDate.of(nextYear.getYear(), Month.JANUARY, 1));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDate.of(nextYear.getYear(), Month.DECEMBER, 31).atTime(23, 59, 59));
        }
    },
    PAST_7_DAYS() {
        LocalDate currentDate = LocalDate.now();
        LocalDate past7DaysStart = currentDate.minusDays(7);
        LocalDate past7DaysEnd = currentDate.minusDays(1);

        @Override
        public String startTime() {
            return formatDate(LocalDateTime.of(past7DaysStart, LocalDateTime.MIN.toLocalTime()));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDateTime.of(past7DaysEnd, LocalDateTime.MAX.toLocalTime()));
        }
    },
    PAST_14_DAYS() {
        LocalDate currentDate = LocalDate.now();
        LocalDate past14DaysStart = currentDate.minusDays(14);
        LocalDate past14DaysEnd = currentDate.minusDays(1);

        @Override
        public String startTime() {
            return formatDate(LocalDateTime.of(past14DaysStart, LocalDateTime.MIN.toLocalTime()));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDateTime.of(past14DaysEnd, LocalDateTime.MAX.toLocalTime()));
        }
    },
    PAST_30_DAYS() {
        LocalDate currentDate = LocalDate.now();
        LocalDate past30DaysStart = currentDate.minusDays(30);
        LocalDate past30DaysEnd = currentDate.minusDays(1);

        @Override
        public String startTime() {
            return formatDate(LocalDateTime.of(past30DaysStart, LocalDateTime.MIN.toLocalTime()));
        }

        @Override
        public String entTime() {
            return formatDate(LocalDateTime.of(past30DaysEnd, LocalDateTime.MAX.toLocalTime()));
        }
    },
    ;

    public abstract String startTime();

    public abstract String entTime();

    public static DateFunc getType(String type) {
        return valueOf(type);
    }

    // 格式化日期时间为字符串
    private static String formatDate(LocalDate date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return date.format(formatter);
    }

    // 格式化日期时间为字符串
    private static String formatDate(LocalDateTime dateTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dateTime.format(formatter);
    }

    public static void main(String[] args) {
        // 获取今天的时间范围
       String  startTime =getType("TODAY").startTime();
        String  endTime = getType("TODAY").entTime();
        System.out.println("今天的时间范围：" + startTime + " - " + endTime);
    }

}